home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Science / µSim 1.0b5 folder / Libs / StdGetFolder.c < prev    next >
Encoding:
Text File  |  1994-09-01  |  6.8 KB  |  290 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. /* I did not write the code in this file; I took it from some sample code
  11. from Apple, I think.
  12. I modified the original code a little bit, though. */
  13.  
  14. //#pragma load "MacDump"
  15.  
  16. #include    "StdGetFolder.h"
  17. #include    "UtilsSys7.h"
  18.  
  19. /* prototypes */
  20.  
  21. static pascal short MyDlgHook(short item,DialogPtr theDlg,Ptr userData);
  22. static pascal Boolean MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr myData);
  23. static void HitButton(DialogPtr theDlg,short item);
  24. static pascal Boolean FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr);
  25. static void SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg);
  26. static Boolean SameFile(FSSpec *file1,FSSpec *file2);
  27. static Boolean GetFSSpecPartialName(FSSpec *file,StringPtr fName);
  28. static OSErr GetDeskFolderSpec(FSSpec *fSpec,short vRefNum);
  29. static OSErr MakeCanonFSSpec(FSSpec *fSpec);
  30. static Boolean ShouldHiliteSelect(FSSpec *fSpec);
  31.  
  32. /* typedefs */
  33.  
  34. typedef struct {
  35.     StandardFileReply *replyPtr;
  36.     FSSpec oldSelection;
  37. } SFData, *SFDataPtr;
  38.  
  39. /* constants */
  40.  
  41. #define    kSelectItem            10
  42. #define    kSFDlg                128
  43. #define    kCanSelectDesktop    true
  44. #define    kSelectStrRsrc        129
  45. #define    kDeskStrRsrc        130
  46. #define    kSelectKey            's'
  47.  
  48. /* globals */
  49.  
  50. Boolean    gHasFindFolder;
  51. FSSpec    gDeskFolderSpec;
  52.  
  53. /*
  54.     strHndl = GetString(kSelectStrRsrc);
  55.     strHndl = GetString(kDeskStrRsrc);
  56. */
  57.  
  58. /* do getfile */
  59.  
  60. Boolean CustomGet(FSSpec *fSpec)
  61. {
  62. FileFilterYDUPP    FilterAllFilesUPP = NewFileFilterYDProc(FilterAllFiles);
  63. DlgHookYDUPP    MyDlgHookUPP = NewDlgHookYDProc(MyDlgHook);
  64. ModalFilterYDUPP    MyModalFilterUPP = NewModalFilterYDProc(MyModalFilter);
  65. Point    where = {-1,-1};
  66. StandardFileReply    sfReply;
  67. SFData    sfUserData;
  68. Boolean    targetIsFolder, wasAliased;
  69.  
  70. /* initialize user data area */
  71.  
  72. sfUserData.replyPtr = &sfReply;
  73. sfUserData.oldSelection.vRefNum = -9999;    /* init to ridiculous value */
  74.  
  75. CustomGetFile(FilterAllFilesUPP, -1, nil, &sfReply, kSFDlg, where, MyDlgHookUPP,
  76.                 MyModalFilterUPP, nil, nil, &sfUserData);
  77.  
  78. if (sfReply.sfGood) {
  79.     if (ResolveAliasFile(&sfReply.sfFile, true, &targetIsFolder, &wasAliased))
  80.         sfReply.sfGood = false;
  81.     else if (FSMakeFSSpec(sfReply.sfFile.vRefNum, sfReply.sfFile.parID, sfReply.sfFile.name, fSpec))
  82.         sfReply.sfGood = false;
  83.     }
  84.  
  85. if (MyModalFilterUPP)
  86.     DisposeRoutineDescriptor(MyModalFilterUPP);
  87. if (MyDlgHookUPP)
  88.     DisposeRoutineDescriptor(MyDlgHookUPP);
  89. if (FilterAllFilesUPP)
  90.     DisposeRoutineDescriptor(FilterAllFilesUPP);
  91.  
  92. return sfReply.sfGood;
  93. }
  94.  
  95.  
  96. /*    this dialog hook checks the contents of the additional edit fields
  97.     when the user selects a file.  The focus of the dialog is changed if one
  98.     of the fields is out of range.
  99. */
  100.  
  101. pascal short MyDlgHook(short item,DialogPtr theDlg,Ptr userData)
  102. {
  103. SFDataPtr sfUserData;
  104. FSSpec curSpec;
  105. OSType refCon;
  106.  
  107. refCon = GetWRefCon(theDlg);
  108. if (refCon != sfMainDialogRefCon)
  109.     return item;
  110.     
  111. sfUserData = (SFDataPtr) userData;
  112.  
  113. if (item==sfHookFirstCall || item==sfHookLastCall)
  114.     return item;
  115.  
  116. if (item==sfItemVolumeUser) {
  117.     sfUserData->replyPtr->sfFile.name[0] = '\0';
  118.     sfUserData->replyPtr->sfFile.parID = 2;
  119.     sfUserData->replyPtr->sfIsFolder = false;
  120.     sfUserData->replyPtr->sfIsVolume = false;
  121.     sfUserData->replyPtr->sfFlags = 0;
  122.     item = sfHookChangeSelection;
  123.     }
  124.     
  125. if (!SameFile(&sfUserData->replyPtr->sfFile,&sfUserData->oldSelection)) {
  126.     curSpec = sfUserData->replyPtr->sfFile;
  127.     MakeCanonFSSpec(&curSpec);
  128.     
  129.     if (curSpec.vRefNum != sfUserData->oldSelection.vRefNum)
  130.         GetDeskFolderSpec(&gDeskFolderSpec,curSpec.vRefNum);    
  131.     SetSelectButtonName(curSpec.name,ShouldHiliteSelect(&curSpec),theDlg);
  132.     
  133.     sfUserData->oldSelection = sfUserData->replyPtr->sfFile;
  134.     }
  135.  
  136. if (item == kSelectItem)
  137.     item = sfItemOpenButton;
  138.     
  139. return item;
  140. }
  141.  
  142.  
  143. pascal Boolean MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr /*myData*/)
  144. {
  145. Boolean evHandled;
  146. char keyPressed;
  147. OSType refCon;
  148.  
  149. refCon = GetWRefCon(theDlg);
  150. if (refCon != sfMainDialogRefCon)
  151.     return false;
  152.     
  153. evHandled = false;
  154.  
  155. switch (ev->what) {
  156.     case keyDown:
  157.     case autoKey:
  158.         keyPressed = CHARFROMMESSAGE(ev->message);
  159.         if ((ev->modifiers & cmdKey) != 0) {
  160.             switch (keyPressed) {
  161.                 case kSelectKey:
  162.                     HitButton(theDlg,kSelectItem);
  163.                     *itemHit = kSelectItem;
  164.                     evHandled = true;
  165.                     break;
  166.             }
  167.         }
  168.         break;
  169. }
  170.  
  171. return evHandled;
  172. }
  173.  
  174.  
  175. void HitButton(DialogPtr theDlg, short item)
  176. {
  177. Rect iRect;
  178. ControlHandle iHndl;
  179. long fTicks;
  180. short iType;
  181.  
  182. GetDItem(theDlg, item, &iType, (Handle *)&iHndl, &iRect);
  183. HiliteControl(iHndl,inButton);
  184. Delay(5L, &fTicks);
  185. HiliteControl(iHndl,0);
  186. }
  187.  
  188.  
  189. pascal Boolean FilterAllFiles(CInfoPBPtr pb, Ptr /*myDataPtr*/)
  190. {/* file is a directory */
  191. return ((pb->hFileInfo.ioFlAttrib & (1<<4)) == 0);
  192. }
  193.  
  194.  
  195. void SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg)
  196. {
  197. Str255 storeName, tempLenStr, tempSelName;
  198. Rect iRect;
  199. StringHandle    theString;
  200. Handle iHndl;
  201. short iType;
  202. short btnWidth;
  203.  
  204. (void) PLstrcpy(tempSelName, selName);
  205. GetDItem(theDlg,kSelectItem,&iType,&iHndl,&iRect);
  206.  
  207. /* truncate select name to fit in button */
  208.  
  209. btnWidth = iRect.right - iRect.left;
  210. theString = GetString(kSelectStrRsrc);
  211.  
  212. (void) PLstrcpy(tempLenStr, *theString);
  213.  
  214. PLstrcat((StringPtr)tempLenStr,"\p “”  ");
  215. btnWidth -= StringWidth(tempLenStr);
  216. TruncString(btnWidth,tempSelName,smTruncMiddle);
  217.  
  218. (void) PLstrcpy(storeName, *theString);
  219. PLstrcat((StringPtr)storeName,"\p “");
  220. PLstrcat((StringPtr)storeName,(StringPtr)tempSelName);
  221. PLstrcat((StringPtr)storeName,"\p”");
  222.  
  223. SetCTitle((ControlHandle)iHndl,storeName);
  224.  
  225. SetDItem(theDlg,kSelectItem,iType,iHndl,&iRect);
  226.  
  227. HiliteControl((ControlHandle)iHndl, hilited ? 0 : 255);
  228. }
  229.  
  230.  
  231. Boolean SameFile(FSSpec *file1,FSSpec *file2)
  232. {
  233. return ((file1->vRefNum == file2->vRefNum) &&
  234.         (file1->parID == file2->parID) &&
  235.         (EqualString(file1->name,file2->name,false,true)));
  236. }
  237.  
  238.  
  239. OSErr GetDeskFolderSpec(FSSpec *fSpec,short vRefNum)
  240. {
  241. register OSErr err;
  242.  
  243. if (gHasFindFolder == false) {
  244.     fSpec->vRefNum = -9999;
  245.     return -1;
  246.     }
  247.  
  248. fSpec->name[0] = '\0';
  249. err = FindFolder(vRefNum,kDesktopFolderType,kDontCreateFolder,
  250.                     &fSpec->vRefNum,&fSpec->parID);
  251. if (err == noErr)
  252.     err = MakeCanonFSSpec(fSpec);
  253.  
  254. return err;
  255. }
  256.  
  257.  
  258. Boolean ShouldHiliteSelect(FSSpec *fSpec)
  259. {
  260. StringHandle    strHndl;
  261.  
  262. if (SameFile(fSpec,&gDeskFolderSpec)) {
  263.     strHndl = GetString(kDeskStrRsrc);
  264.     (void) PLstrcpy(fSpec->name, *strHndl);
  265.     return kCanSelectDesktop;
  266.     }
  267. else
  268.     return true;
  269. }
  270.  
  271.  
  272. OSErr MakeCanonFSSpec(FSSpec *fSpec)
  273. {
  274. DirInfo infoPB;
  275. OSErr err;
  276.  
  277. if (fSpec->name[0] != '\0')
  278.     return noErr; /* controllare */
  279.     
  280. infoPB.ioNamePtr = fSpec->name;
  281. infoPB.ioVRefNum = fSpec->vRefNum;
  282. infoPB.ioDrDirID = fSpec->parID;
  283. infoPB.ioFDirIndex = -1;
  284. err = PBGetCatInfo((CInfoPBPtr)&infoPB,false);
  285. fSpec->parID = infoPB.ioDrParID;
  286.  
  287. return err;
  288. }
  289.  
  290.